{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 神经网络解决多分类问题¶\n",
    "## 案例： 手写数字识别\n",
    "## 数据集：ex3data1.mat\n",
    "## 参数：ex3weights.mat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy.io as sio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(5000, 400)\n",
      "(5000, 1)\n"
     ]
    }
   ],
   "source": [
    "data = sio.loadmat('ex3data1.mat')\n",
    "raw_X = data['X']\n",
    "raw_y = data['y']\n",
    "print(raw_X.shape)  # 5000个样本 20*20的图像\n",
    "print(raw_y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "(5000, 401)"
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = np.insert(raw_X, 0, values=1, axis=1)\n",
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "(5000,)"
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = raw_y.flatten()  # 方便算准确率\n",
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "dict_keys(['__header__', '__version__', '__globals__', 'Theta1', 'Theta2'])"
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta = sio.loadmat('ex3weights.mat')\n",
    "theta.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "((25, 401), (10, 26))"
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta1 = theta['Theta1']  # 输入层到隐藏层  25个神经元\n",
    "theta2 = theta['Theta2']  # 隐藏层最后 10个输出神经元\n",
    "theta1.shape, theta2.shape\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sigmoid(z):\n",
    "    return 1 / (1 + np.exp(-z))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "(5000, 401)"
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a1 = X\n",
    "a1.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 5000,401 * 401,25\n",
    "z2 = a1 @ theta1.T\n",
    "a2 = sigmoid(z2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "outputs": [
    {
     "data": {
      "text/plain": "(5000, 25)"
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a2.shape"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "(5000, 26)"
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a2 = np.insert(a2, 0, values=1, axis=1)\n",
    "a2.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [],
   "source": [
    "z3 = a2 @ theta2.T\n",
    "a3 = sigmoid(z3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "(5000, 10)"
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a3.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(5000,)\n",
      "[9 9 9 ... 8 8 8]\n"
     ]
    }
   ],
   "source": [
    "y_pred = np.argmax(a3, axis=1)  # 获取array的维度2中 数值最大(概率最大)的那个元素的索引\n",
    "print(y_pred.shape)\n",
    "print(y_pred)\n",
    "y_pred = y_pred + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [],
   "source": [
    "acc = np.mean(y_pred == y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "0.9752"
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "acc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "array([[1.12661530e-04, 1.74127856e-03, 2.52696959e-03, ...,\n        4.01468105e-04, 6.48072305e-03, 9.95734012e-01],\n       [4.79026796e-04, 2.41495958e-03, 3.44755685e-03, ...,\n        2.39107046e-03, 1.97025086e-03, 9.95696931e-01],\n       [8.85702310e-05, 3.24266731e-03, 2.55419797e-02, ...,\n        6.22892325e-02, 5.49803551e-03, 9.28008397e-01],\n       ...,\n       [5.17641791e-02, 3.81715020e-03, 2.96297510e-02, ...,\n        2.15667361e-03, 6.49826950e-01, 2.42384687e-05],\n       [8.30631310e-04, 6.22003774e-04, 3.14518512e-04, ...,\n        1.19366192e-02, 9.71410499e-01, 2.06173648e-04],\n       [4.81465717e-05, 4.58821829e-04, 2.15146201e-05, ...,\n        5.73434571e-03, 6.96288990e-01, 8.18576980e-02]])"
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
